import os

import speedtest
from flask import flash, redirect, url_for
from flask_admin import expose
from flask_admin.helpers import get_form_data
from markupsafe import Markup

from app.database.models import Order
from app.server.flask_app import db
from app.server.flask_app.admin_views import MyBaseModelView


def _get_expiring(view, context, model, name):
    order = db.session.query(Order).filter(Order.proxies.contains(model)).first()
    if order:
        return order.expiring_on
    return None


class ProxyModelView(MyBaseModelView):
    column_list = (
        "id",
        "server.ip_address",
        "server.proxy_type",
        "server.proxy_privacy",
        "status",
        "server.country",
        "port_https",
        "server.categories",
        "orders",
        "users",
        "was_added",
        "expiring_on",
        "check_speed",
    )

    def _check_proxy_speed(view, context, model, name):

        # render a form with a submit button for student, include a hidden field for the student id
        # note how checkout_view method is exposed as a route below
        check_proxy_url = url_for(".check_proxy_view")

        _html = f"""
            <form action="{check_proxy_url}" method="POST">
                <input id="proxy_id" name="proxy_id"  type="hidden" value="{model.id}">
                <button class="btn btn-primary" type="submit">Check</button>
            </form
        """

        return Markup(_html)

    column_formatters = {
        "expiring_on": _get_expiring,
        "check_speed": _check_proxy_speed,
    }

    @expose("check", methods=["POST"])
    def check_proxy_view(self):

        return_url = self.get_url(".index_view")
        form = get_form_data()
        # import pdb
        # pdb.set_trace()

        if not form:
            flash("Could not get form from request.", "error")
            return redirect(return_url)

        proxy_id = form["proxy_id"]

        model = self.get_one(proxy_id)

        if model is None:
            flash("Proxy not found.", "error")
            return redirect(return_url)

        try:
            os.environ[
                "HTTP_PROXY"
            ] = f"http://{model.login}:{model.password}@{model.server.ip_address}:{model.port_https}"
            os.environ[
                "HTTPS_PROXY"
            ] = f"http://{model.login}:{model.password}@{model.server.ip_address}:{model.port_https}"
            os.environ[
                "http_proxy"
            ] = f"http://{model.login}:{model.password}@{model.server.ip_address}:{model.port_https}"
            os.environ[
                "https_proxy"
            ] = f"http://{model.login}:{model.password}@{model.server.ip_address}:{model.port_https}"

            st = speedtest.Speedtest()
            st.get_best_server()
            download_speed = round(st.download() / 1e6, 2)
            upload_speed = round(st.upload() / 1e6, 2)

            flash(
                f"Download speed: {download_speed} Mbps. Upload speed: {upload_speed} Mbps",
                "success",
            )
        except Exception as e:
            flash(f"Failed to speed of proxy №{proxy_id}. Error: {str(e)}", "error")

        return redirect(return_url)

    column_editable_list = (
        "login",
        "password",
        "port_https",
        "was_added",
    )

    column_searchable_list = (
        "status",
        "user_id",
        "port_https",
    )

    column_filters = (
        "status",
        "users",
        "was_added",
        "login",
        "password",
        "authorization_type",
        "reload_type",
        "server.ip_address",
        "server.country",
        "server.categories",
        "server.proxy_type",
        "server.proxy_privacy",
    )
